﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data.MySqlClient;
using DTO;

namespace DAL
{
    public class EquipamentoDal : AbstractDal
    {
        public Equipamento Selecionar(int id)
        {
            try
            {
                AbrirConexao();
                string query = "SELECT e.* FROM equipamento e where id = @id";

                if (Config.Debug)
                    Log.Write(query); 
                
                
                MySqlCommand com = new MySqlCommand(query, conn);
                com.Parameters.AddWithValue("@id", id);
                MySqlDataReader reader = com.ExecuteReader();
                while (reader.Read())
                {
                    return ExtrairEntidade(reader);
                }
                return null;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }
        public List<Equipamento> Buscar(string busca, List<int> tipos)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                AbrirConexao();
                string strTipos = ConcatenarListaInt(tipos);

                string query = @"SELECT e.*, CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco FROM equipamento e where MATCH(nome, bairro, rua) AGAINST(@query)"
                + (tipos.Count > 0 ? " and tipo in (" + strTipos + ")" : string.Empty );

                if (Config.Debug)
                    Log.Write(query); 
                
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@query", busca);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }

                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }
        public List<Equipamento> Buscar(string nome, string rua, string bairro, List<int> tipos)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                string strTipos = ConcatenarListaInt(tipos);
                AbrirConexao();
                string query = 
                    @"SELECT e.*, 
                             CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco 
                            FROM 
                            equipamento e 
                            where (LOWER(nome) like @nome or LOWER(rua) like @rua or LOWER(bairro) like @bairro) " 
                            + (tipos.Count > 0 ? " and tipo in (" + strTipos + ")" : string.Empty );

                if (Config.Debug)
                    Log.Write(query); 
                

                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@rua", "%" + rua.ToLower() + "%");
                cmd.Parameters.AddWithValue("@bairro", "%" + bairro.ToLower() + "%");
                cmd.Parameters.AddWithValue("@nome", "%" + nome.ToLower() + "%");
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }
        public List<Equipamento> SelecionarTodos()
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                AbrirConexao();
                string query = "SELECT e.*, CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco FROM equipamento e";

                if (Config.Debug)
                    Log.Write(query); 
                
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                MySqlDataReader reader = cmd.ExecuteReader();

                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }
        public List<Equipamento> SelecionarTodos(TipoEquipamento tipo)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                AbrirConexao();
                string query = "SELECT e.*, CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco FROM equipamento e WHERE tipo = @tipo";


                if (Config.Debug)
                    Log.Write(query);
                
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@tipo", (int)tipo);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }

        /// <summary>
        /// Cadastra um novo equipamento.
        /// </summary>
        /// <param name="museu">O equipamento a ser cadastrado.</param>
        /// <returns>Retorna o id do equipamento cadastrado.</returns>
        public int Inserir(Equipamento e)
        {
            try
            {
                AbrirConexao();
                string query = @"INSERT INTO equipamento 
                    (tipo, tipodetalhado, nome, descricao, email, site, telefone, fax, bairro, rua, numero, cep, capacidade, especialidade, unidadeshabitacionais, cenario, nolocal, nohotel, rotas, companhia, couvert, formaspagamento, faixaprecos, equipamentos, servicos, horariofuncionamento, tarifas, reservas) 
                    values
                    (@tipo, @tipodetalhado, @nome, @descricao, @email, @site, @telefone, @fax, @bairro, @rua, @numero, @cep, @capacidade, @especialidade, @unidadeshabitacionais, @cenario, @nolocal, @nohotel, @rotas, @companhia, @couvert, @formaspagamento, @faixaprecos, @equipamentos, @servicos, @horariofuncionamento, @tarifas, @reservas)";
                MySqlCommand com = new MySqlCommand(query, conn);
                com.Parameters.AddWithValue("@nome", e.Nome);
                com.Parameters.AddWithValue("@tipo", (int) e.Tipo);
                com.Parameters.AddWithValue("@tipodetalhado", e.TipoDetalhado);
                com.Parameters.AddWithValue("@descricao", e.Descrição);
                com.Parameters.AddWithValue("@email", e.Email);
                com.Parameters.AddWithValue("@site", e.Site);
                com.Parameters.AddWithValue("@telefone", e.Telefone);
                com.Parameters.AddWithValue("@fax", e.Fax);
                com.Parameters.AddWithValue("@bairro", e.Bairro);
                com.Parameters.AddWithValue("@rua", e.Rua);
                com.Parameters.AddWithValue("@numero", e.Numero);
                com.Parameters.AddWithValue("@cep", e.Cep);
                com.Parameters.AddWithValue("@capacidade", e.Capacidade);
                com.Parameters.AddWithValue("@especialidade", e.Especialidade);
                com.Parameters.AddWithValue("@unidadeshabitacionais", e.UnidadesHabitacionais);
                com.Parameters.AddWithValue("@cenario", e.Cenário);
                com.Parameters.AddWithValue("@nolocal", e.NoLocal);
                com.Parameters.AddWithValue("@nohotel", e.NoHotel);
                com.Parameters.AddWithValue("@rotas", e.Rotas);
                com.Parameters.AddWithValue("@companhia", e.Companhia);
                com.Parameters.AddWithValue("@couvert", e.Couvert);
                com.Parameters.AddWithValue("@formaspagamento", e.FormasPagamento);
                com.Parameters.AddWithValue("@faixaprecos", e.FaixaPreços);
                com.Parameters.AddWithValue("@equipamentos", e.Equipamentos);
                com.Parameters.AddWithValue("@servicos", e.Serviços);
                com.Parameters.AddWithValue("@horariofuncionamento", e.HorarioFuncionamento);
                com.Parameters.AddWithValue("@tarifas", e.Tarifas);
                com.Parameters.AddWithValue("@reservas", e.Reservas);
                com.ExecuteNonQuery();
                FecharConexao();
                AbrirConexao();
                query = "SELECT @@IDENTITY as ID";
                com = new MySqlCommand(query, conn);
                com.Parameters.Clear();
                MySqlDataReader reader = com.ExecuteReader();
                if (reader.Read())
                    return Convert.ToInt32(reader["id"]);
                return 0;

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharConexao();
            }
        }
        /// <summary>
        /// Altera um equipametno já cadastrado.
        /// </summary>
        /// <param name="e">O equipamento. Deve possuir o ID correto.</param>
        /// <returns>Retorna 0 caso não tenha afetado nenhum registro</returns>
        public int Alterar(Equipamento e)
        {
            try
            {
                AbrirConexao();
                string query = @"UPDATE equipamento SET
                                    tipo = @tipo, 
                                    tipodetalhado = @tipodetalhado, 
                                    nome= @nome, 
                                    descricao = @descricao, 
                                    email = @email, 
                                    site= @site, 
                                    telefone = @telefone, 
                                    fax= @fax, 
                                    bairro = @bairro, 
                                    rua = @rua, 
                                    numero = @numero, 
                                    cep= @cep, 
                                    capacidade = @capacidade, 
                                    especialidade = @especialidade, 
                                    unidadeshabitacionais = @unidadeshabitacionais, 
                                    cenario = @cenario, 
                                    nolocal = @nolocal, 
                                    nohotel = @nohotel, 
                                    rotas = @rotas, 
                                    companhia = @companhia, 
                                    couvert  = @couvert, 
                                    formaspagamento = @formaspagamento, 
                                    faixaprecos = @faixaprecos, 
                                    equipamentos = @equipamentos, 
                                    servicos = @servicos, 
                                    horariofuncionamento = @horariofuncionamento,
                                    reservas = @reservas
                                    where id = @id";

                MySqlCommand com = new MySqlCommand(query, conn);
                com.Parameters.AddWithValue("@id", e.Id);
                com.Parameters.AddWithValue("@nome", e.Nome);
                com.Parameters.AddWithValue("@tipo", (int)e.Tipo);
                com.Parameters.AddWithValue("@tipodetalhado", e.TipoDetalhado);
                com.Parameters.AddWithValue("@descricao", e.Descrição);
                com.Parameters.AddWithValue("@email", e.Email);
                com.Parameters.AddWithValue("@site", e.Site);
                com.Parameters.AddWithValue("@telefone", e.Telefone);
                com.Parameters.AddWithValue("@fax", e.Fax);
                com.Parameters.AddWithValue("@bairro", e.Bairro);
                com.Parameters.AddWithValue("@rua", e.Rua);
                com.Parameters.AddWithValue("@numero", e.Numero);
                com.Parameters.AddWithValue("@cep", e.Cep);
                com.Parameters.AddWithValue("@capacidade", e.Capacidade);
                com.Parameters.AddWithValue("@especialidade", e.Especialidade);
                com.Parameters.AddWithValue("@unidadeshabitacionais", e.UnidadesHabitacionais);
                com.Parameters.AddWithValue("@cenario", e.Cenário);
                com.Parameters.AddWithValue("@nolocal", e.NoLocal);
                com.Parameters.AddWithValue("@nohotel", e.NoHotel);
                com.Parameters.AddWithValue("@rotas", e.Rotas);
                com.Parameters.AddWithValue("@companhia", e.Companhia);
                com.Parameters.AddWithValue("@couvert", e.Couvert);
                com.Parameters.AddWithValue("@formaspagamento", e.FormasPagamento);
                com.Parameters.AddWithValue("@faixaprecos", e.FaixaPreços);
                com.Parameters.AddWithValue("@equipamentos", e.Equipamentos);
                com.Parameters.AddWithValue("@servicos", e.Serviços);
                com.Parameters.AddWithValue("@horariofuncionamento", e.HorarioFuncionamento);
                com.Parameters.AddWithValue("@reservas", e.Reservas);
                return com.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                FecharConexao();
            }

        }
        
        private Equipamento ExtrairEntidade(MySqlDataReader reader)
        {
            Equipamento e = new Equipamento();
            e.Id = ExtrairInt(reader, "id");
            e.Tipo = (TipoEquipamento) ExtrairInt(reader, "tipo");
            e.TipoDetalhado = ExtrairInt(reader, "tipodetalhado");
            e.Nome = ExtrairString(reader, "nome");
            e.Descrição = ExtrairString(reader, "descricao");
            e.Email = ExtrairString(reader, "email");
            e.Site = ExtrairString(reader, "site");
            e.Telefone = ExtrairString(reader, "telefone");
            e.Fax = ExtrairString(reader, "fax");
            e.Bairro = ExtrairString(reader, "bairro");
            e.Rua = ExtrairString(reader, "rua");
            e.Numero = ExtrairString(reader, "numero");
            e.Cep = ExtrairString(reader, "cep");
            e.Endereco = string.Format("{0}, {1}, {2}", e.Rua, e.Numero, e.Bairro);
            e.Capacidade = ExtrairString(reader, "capacidade");
            e.Especialidade = ExtrairString(reader, "especialidade");
            e.UnidadesHabitacionais = ExtrairString(reader, "unidadeshabitacionais");
            e.Cenário = ExtrairString(reader, "cenario");
            e.NoLocal = ExtrairString(reader, "nolocal");
            e.NoHotel = ExtrairString(reader, "nohotel");
            e.Rotas = ExtrairString(reader, "rotas");
            e.Companhia = ExtrairString(reader, "companhia");
            e.Couvert = ExtrairString(reader, "couvert");
            e.FormasPagamento = ExtrairString(reader, "formaspagamento");
            e.FaixaPreços = ExtrairString(reader, "faixaprecos");
            e.Equipamentos = ExtrairString(reader, "equipamentos");
            e.Serviços = ExtrairString(reader, "servicos");
            e.HorarioFuncionamento = ExtrairString(reader, "horariofuncionamento");
            e.Tarifas = ExtrairString(reader, "tarifas");
            e.Reservas = ExtrairString(reader, "reservas");
            return e;
        }
        private string ExtrairString(MySqlDataReader reader, string parameter)
        {
            return reader[parameter] == DBNull.Value ? string.Empty : Convert.ToString(reader[parameter]);
        }
        private int ExtrairInt(MySqlDataReader reader, string parameter)
        {
            return reader[parameter] == DBNull.Value ? 0 : Convert.ToInt32(reader[parameter]);
        }
        private string ConcatenarListaInt(List<int> tipos)
        {
            string str = string.Empty;

            if (tipos.Count > 0)
            {
                for (int i = 0; i < tipos.Count - 1; i++)
                {
                    str += tipos[i] + ",";
                }

                str += tipos[tipos.Count - 1];
            }
            return str;
        }


        public List<Equipamento> SelecionarTodos(TipoEquipamento tipo, int TipoDetalhadoParam)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                AbrirConexao();
                string query = "SELECT e.*, CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco FROM equipamento e WHERE tipo = @tipo && tipodetalhado = @tipodetalhado";
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@tipo", (int)tipo);
                cmd.Parameters.AddWithValue("@tipodetalhado", TipoDetalhadoParam);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                } 
                
                if (Config.Debug)
                    Log.Write(query);
                
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }

        

        public int ExcluirEquipamento(int id)
        {
            try
            {
                AbrirConexao();
                string query = "DELETE FROM equipamento WHERE id = @id";
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@id", id);
                return cmd.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }

        public List<Equipamento> Buscar(string busca, TipoEquipamento tipo, List<int> tipos)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                string strTipos = ConcatenarListaInt(tipos);
                AbrirConexao();
                string query =
                    @"SELECT e.*, 
                             CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco 
                            FROM 
                            equipamento e 
                            where match(nome, descricao, bairro, rua) against (@query in boolean mode)
                            and tipo = @tipo"
                            + (tipos.Count > 0 ? " and tipodetalhado in (" + strTipos + ")" : string.Empty);


                if (Config.Debug)
                    Log.Write(query);
                
                
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@query", busca);
                cmd.Parameters.AddWithValue("@tipo", (int)tipo);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }

        public List<Equipamento> Buscar(string busca)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                AbrirConexao();
                string query =
                    @"SELECT e.*, 
                             CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco 
                            FROM 
                            equipamento e 
                            where match(nome, descricao, bairro, rua) against (@query in boolean mode)";

                if (Config.Debug)
                    Log.Write(query);
                
                

                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@query", busca);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }


        public List<Equipamento> SelecionarTodos(TipoEquipamento tipo, List<int> tipos)
        {
            try
            {
                List<Equipamento> lista = new List<Equipamento>();
                string strTipos = ConcatenarListaInt(tipos);
                AbrirConexao();
                string query =
                    @"SELECT e.*, 
                             CONCAT(e.rua,', ',e.numero,', ',e.bairro) as endereco 
                            FROM 
                            equipamento e 
                            where tipo = @tipo"
                            + (tipos.Count > 0 ? " and tipodetalhado in (" + strTipos + ")" : string.Empty);


                if (Config.Debug)
                    Log.Write(query);
                
                
                MySqlDataAdapter da = new MySqlDataAdapter(query, conn);
                MySqlCommand cmd = new MySqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@tipo", (int)tipo);
                MySqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    lista.Add(ExtrairEntidade(reader));
                }
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                FecharConexao();
            }
        }

    }
}